import { combineReducers, configureStore } from "@reduxjs/toolkit"
import { useDispatch, useSelector } from "react-redux"
import type { TypedUseSelectorHook } from "react-redux"
import { syncStorage } from "redux-persist-webextension-storage"

import {
    FLUSH,
    PAUSE,
    PERSIST,
    persistReducer,
    persistStore,
    PURGE,
    REGISTER,
    REHYDRATE,
    RESYNC
} from "@plasmohq/redux-persist"
import { Storage } from "@plasmohq/storage"

import funcTabs from "./controller/funcTabs"
import jinritemaiDecrypt from "./controller/jinritemaiDecrypt"
import jinritemaiProduct from "./controller/jinritemaiProduct"
import jinritemaiShops from "./controller/jinritemaiShops"

// Here you can add all your reducers
const combinedReducers = combineReducers({
    funcTabs,
    jinritemaiDecrypt,
    jinritemaiProduct,
    jinritemaiShops
})

const persistConfig = {
    key: "wtplugwt-in",
    version: 1,
    storage: syncStorage,
    whitelist: [''] // 白名单只有test2会被持久化 在这里添加需要持久化的name
}

// TODO: Fix persistReducer so it doesn't break the types
const persistedReducer = persistReducer(persistConfig, combinedReducers)

// 获取 configureStore 的数据类型
const mockStore = configureStore({
    reducer: combinedReducers
})

// @ts-ignore
// 再将数据类型进行匹配语法需要
export const store = configureStore({
    reducer: persistedReducer,
    // 中间件
    middleware: (getDefaultMiddleware) =>
        getDefaultMiddleware({
            serializableCheck: {
                ignoredActions: [
                    FLUSH,
                    REHYDRATE,
                    PAUSE,
                    PERSIST,
                    PURGE,
                    REGISTER,
                    RESYNC
                ]
            }
        })
}) as typeof mockStore

export const persistor = persistStore(store) // 到处持久化存储

// 监听Redux 数据变化并更新Storage
new Storage().watch({
    [`persist:${persistConfig.key}`]: (change) => {
        const { oldValue, newValue } = change
        const updatedKeys = []
        for (const key in oldValue) {
            if (oldValue[key] !== newValue?.[key]) {
                updatedKeys.push(key)
            }
        }
        for (const key in newValue) {
            if (oldValue?.[key] !== newValue[key]) {
                updatedKeys.push(key)
            }
        }
        if (updatedKeys.length > 0) {
            persistor?.resync()
        }
    }
})

// Get the types from the mock store
export type RootState = ReturnType<typeof mockStore.getState>
export type AppDispatch = typeof mockStore.dispatch

// Export the hooks with the types from the mock store
export const useAppDispatch: () => AppDispatch = useDispatch
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector
